﻿using System;
using Ewk.Runtime.Serialization.PositionBased;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Ewk.Runtime.Serialization.UnitTests.PositionBased
{
    /// <summary>
    /// Summary description for PositionBasedInt32SerializerTests
    /// </summary>
    [TestClass]
    public class PositionBasedInt32SerializerTests
    {
        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod, ExpectedException(typeof(DatafieldSerializationException))]
        public void PositionBasedInt32Serializer_cannot_deserialize_an_invalid_string_representation_of_an_Int32()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 1) { DefaultCharacter = '0' };

            fieldSerializer.Deserialize("X", fieldAttribute);
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_cannot_deserialize_an_invalid_string_representation_of_an_Int32_when_a_client_subscribes_on_the_serializationfailed_event()
        {
            string message = null;
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 1) { DefaultCharacter = '0' };

            fieldSerializer.DatafieldSerializationFailed +=
                delegate(object sender, DatafieldSerializationFailedEventArgs e)
                {
                    message = e.Message;
                };

            fieldSerializer.Deserialize("X", fieldAttribute);

            Assert.IsInstanceOfType(message, typeof(string));
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_serialize_a_neqative_Int32_to_a_Int32_string_with_default_format()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) {DefaultCharacter = '0'};

            for (var i = -99; i < -9; i++)
            {
                var result = fieldSerializer.Serialize(i, fieldAttribute);

                Assert.AreEqual(10, result.Length, "Incorrect length");
                Assert.AreEqual(i.ToString("0000000000;-000000000"), result, "Incorrect value");
            }
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_serialize_a_positive_Int32_to_a_Int32_string_with_default_format()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) { DefaultCharacter = '0' };

            for (var i = 10; i < 100; i++)
            {
                var result = fieldSerializer.Serialize(i, fieldAttribute);

                Assert.AreEqual(10, result.Length, "Incorrect length");
                Assert.AreEqual(i.ToString("0000000000;-000000000"), result, "Incorrect value");
            }
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_serialize_a_zero_Int32_to_a_Int32_string_with_default_format()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) { DefaultCharacter = '0' };

            var result = fieldSerializer.Serialize(0, fieldAttribute);
            Assert.AreEqual("0000000000", result, "Incorrect value");
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_serialize_a_zero_Int32_to_a_Int32_string_with_aberrant_DefaultCharacter()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) { DefaultCharacter = 'X' };

            var result = fieldSerializer.Serialize(0, fieldAttribute);
            Assert.AreEqual("XXXXXXXXXX", result, "Incorrect value");
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_deserialize_a_valid_negative_Int32_string_with_default_format_to_a_Int32_instance()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) { DefaultCharacter = '0' };

            for (var i = -99; i < -9; i++)
            {
                var result = fieldSerializer.Deserialize(i.ToString("0000000000;-000000000"), fieldAttribute);

                Assert.IsInstanceOfType(result, typeof(Int32));

                var typedResult = (Int32)result;
                Assert.AreEqual(i, typedResult);
            }
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_deserialize_a_valid_positive_Int32_string_with_default_format_to_a_Int32_instance()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) { DefaultCharacter = '0' };

            for (var i = 10; i < 100; i++)
            {
                var result = fieldSerializer.Deserialize(i.ToString("0000000000;-000000000"), fieldAttribute);

                Assert.IsInstanceOfType(result, typeof(Int32));

                var typedResult = (Int32)result;
                Assert.AreEqual(i, typedResult);
            }
        }

        [TestMethod]
        public void PositionBasedInt32Serializer_can_deserialize_a_valid_zero_Int32_string_with_default_format_to_a_Int32_instance()
        {
            var fieldSerializer = new PositionBasedInt32Serializer();
            var fieldAttribute = new PositionBasedDatafieldAttribute(0, 10) { DefaultCharacter = '0' };

                var result = fieldSerializer.Deserialize("0000000000", fieldAttribute);

                Assert.IsInstanceOfType(result, typeof(Int32));

                var typedResult = (Int32)result;
                Assert.AreEqual(0, typedResult);
        }
    }
}
